﻿

using System;
using System.Linq;

namespace ZDK.Infra.Helpers
{
    //格式转换
    public static class FmtHelper
    {
        //十进制→BCD
        public static int DecToBCD(int decdata)
        {
            decdata %= 100;
            checked
            {
                return unchecked(decdata % 10) + unchecked(decdata / 10) * 16;
            }
        }
        public static byte[] LongToBCD(long raw, int len)
        {
            byte[] b = new byte[len];
            for (int i = 0; i < len; i++)
            {
                if (raw % 100 < 10)
                    b[i] = (byte)(raw % 100);
                else
                    b[i] = (byte)int.Parse((raw % 100) + "", System.Globalization.NumberStyles.HexNumber);
                raw = raw / 100;
            }
            return b;
        }
        public static long BCDToLong(byte[] raw)
        {
            long b = 0;
            int len = raw.Length;

            for (int i = len - 1; i >= 0; i--)
            {
                b += b * 100 + int.Parse(raw[i].ToString("x"));
            }
            return b;
        }
        public static byte[] LongToBytes(long raw, int len)
        {
            byte[] b = new byte[len];
            for (int i = 0; i < len; i++)
            {
                if (i == 0)
                    b[i] = (byte)(raw & 0xFF);
                else
                    b[i] = (byte)(raw >> 8 * i & 0xFF);
            }
            return b;
        }
        public static long BytesToLong(byte[] raw)
        {
            long b = 0;
            raw = raw.Reverse().ToArray();
            for (int i = 0; i < raw.Length; i++)
            {
                b = b | raw[i];
                if (i < raw.Length - 1)
                    b = b << 8;
            }
            return b;
        }
        //只针对数字转相同显示的hex,例如68->0x68,len为结果数组数
        public static byte[] DoubleToBytes(double raw, int len)
        {
            byte[] b = new byte[len];
            int data = (int)Math.Floor(raw * (Math.Pow(10, len - 1)));
            for (int i = 0; i < len; i++)
            {
                if (data % 100 < 10)
                    b[i] = (byte)(data % 100);
                else
                    b[i] = (byte)int.Parse(data % 100 + "", System.Globalization.NumberStyles.HexNumber);
                data = data / 100;
            }
            if (raw < 0)
                b[len - 1] = (byte)(b[len - 1] | 0x80);
            return b;
        }
        #region 获取附录B数据格式29
        public static double GetAppendB29(byte[] r, int pos)
        {
            int sign = (int)(r[pos + 2] & 0x80) == 0x80 ? -1 : 1;//符号
            var tmp = r[pos + 2] >> 4 & 0x7;
            int qian = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//千位
            tmp = r[pos + 2] & 0xF;
            int bai = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//百位
            tmp = r[pos + 1] >> 4 & 0xF;
            int shi = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//十位
            tmp = r[pos + 1] & 0xF;
            int ge = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//个位
            tmp = r[pos] >> 4 & 0xF;
            int shifen = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//十分位
            tmp = r[pos] & 0xF;
            int baifen = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//百分位
            double num1 = (qian * 1000 + bai * 100 + shi * 10 + ge + shifen / 10.0 + baifen / 100.0) * sign;
            return num1;
        }
        #endregion

        #region 获取附录B数据格式25
        public static double GetAppendB25(byte[] r, int pos)
        {
            int sign = (int)(r[pos + 2] & 0x80) == 0x80 ? -1 : 1;//符号
            var tmp = r[pos + 2] >> 4 & 0x7;
            int bai = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//百位
            tmp = r[pos + 2] & 0xF;
            int shi = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//十位
            tmp = r[pos + 1] >> 4 & 0xF;
            int ge = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//个位
            tmp = r[pos + 1] & 0xF;
            int shifen = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//十分位
            tmp = r[pos] >> 4 & 0xF;
            int baifen = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//百分位
            tmp = r[pos] & 0xF;
            int qianfen = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//千分位
            double num1 = (bai * 100 + shi * 10 + ge + shifen / 10.0 + baifen / 100.0 + qianfen / 1000.0) * sign;
            return num1;
        }
        #endregion

        #region 获取附录B数据格式7
        public static double GetAppendB7(byte[] r, int pos)
        {
            var tmp = r[pos + 1] >> 4 & 0xF;
            int bai = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//百位
            tmp = r[pos + 1] & 0xF;
            int shi = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//十位
            tmp = r[pos] >> 4 & 0xF;
            int ge = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//个位
            tmp = r[pos] & 0xF;
            int shifen = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//十分位
            double num1 = (bai * 100 + shi * 10 + ge + shifen / 10.0);
            return num1;
        }
        #endregion

        #region 获取附录B数据格式2
        public static double GetAppendB2(byte[] r, int pos)
        {
            double pow = 10000;
            int n = r[pos + 1] >> 5;
            pow /= Math.Pow(10, n);
            int sign = (int)(r[pos + 1] & 0x10) == 0x10 ? -1 : 1;//符号
            var tmp = r[pos + 1] & 0xF;
            int bai = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//百位
            tmp = r[pos] >> 4;
            int shi = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//十位
            tmp = r[pos] & 0xF;
            int ge = int.Parse(((byte)(tmp > 9 ? 0 : tmp)).ToString("x"));//个位

            double num1 = (bai * 100 + shi * 10 + ge) * sign * pow;
            return num1;
        }

        public static byte[] uGetAppendB2(double raw)
        {
            byte[] ret = new byte[2];
            string s = $"{raw:e}";
            var arr = s.Split('e');
            double num = double.Parse(arr[0]);
            int mi = int.Parse(arr[1]);
            int bai, shi, ge, g3, g2, g1;
            bai = shi = ge = g3 = g2 = g1 = 0;
            int sign = raw > 0 ? 0 : 1;
            if (mi < 0)
            {
                //小数
                bai = shi = 0;
                ge = (int)(num % 10);
            }
            else
            {
                if (mi > 2)
                {
                    mi -= 2; num *= 100;
                }
                else
                {
                    num *= Math.Pow(10, mi); mi = 0;
                }
                num = (int)(num + 0.5);
                bai = (int)(num / 100 % 10);
                shi = (int)(num / 10 % 10);
                ge = (int)(num % 10);
            }
            switch (mi)
            {
                case -3: g3 = g2 = g1 = 1; break;
                case -2: g3 = g2 = 1; g1 = 0; break;
                case -1: g3 = g1 = 1; g2 = 0; break;
                case 0: g3 = 1; g2 = g1 = 0; break;
                case 1: g3 = 0; g2 = g1 = 1; break;
                case 2: g3 = 0; g2 = 1; g1 = 0; break;
                case 3: g3 = g2 = 0; g1 = 1; break;
                case 4: g3 = g2 = g1 = 0; break;
            }
            ret[0] = StrHelper.StrToHexByte($"{shi}{ge}")[0];
            ret[1] = (byte)((g3 << 7) | (g2 << 6) | (g1 << 5) | (sign << 4) | bai);

            return ret;
            ////十位，各位
            //int nRaw = (int)raw;
            //int shi = nRaw / 10 % 10;
            //int ge = nRaw % 10;
            //ret[0] = (byte)(shi * 256 + ge);

            ////百位
            //int bai = nRaw / 100 % 10;
            ////符号位
            //int sign = nRaw > 0 ? 1 : 0;

            ////G位
            //int mi = 0;

        }
        #endregion
    }
}
